use serde::{ser::SerializeStruct, Serialize};
use thiserror::Error;
#[allow(dead_code)]
#[derive(Debug, Error, Serialize)]
pub enum AppError {
    #[error("unknow database error")]
    UnknownDataBaseError(String),
    #[error("database error: Not Found")]
    NotFound(#[from] rmpredictdb::database_error::DatabaseError),
    #[error("occur error when upload")]
    UploadError(FileError),
    #[error("qinniu service occur error! {0}")]
    QiNiuResponse(String),
    #[error("持久化出现错误！{0}")]
    Persistence(#[from] tauri_plugin_store::Error),
    #[error("使用模型预测时出现错误: {0}")]
    Predict(String),
}

#[derive(Debug, Error)]
pub enum FileError {
    #[error("occur error")]
    Error {
        #[source]
        error: std::io::Error,
        message: String,
    },
}
impl Serialize for FileError {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            FileError::Error { error, message } => {
                let mut state = serializer.serialize_struct("FileError", 3)?;
                state.serialize_field("type", "FileError")?;
                state.serialize_field("message", message)?;
                state.serialize_field("error", &error.to_string())?;
                state.end()
            }
        }
    }
}
impl From<std::io::Error> for FileError {
    fn from(value: std::io::Error) -> Self {
        let message = value.to_string();
        let kinds = value.kind();
        Self::Error {
            error: value,
            message: format!("{}.{}", kinds, message),
        }
    }
}
